﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using AngleSharp.Parser.Html;
using Common.Model;

namespace Spider.Spider
{
    public class SzQaSpider
    {
        private static string GetQuestionHtml(String startTime, String endTime, string pageNo)
        {
            var stringBuilder = new StringBuilder();
            var url = "http://irm.cninfo.com.cn/ircs/interaction/allQuestionsForSzse.do";

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);

            request.Method = WebRequestMethods.Http.Post;

            request.ContentType = "application/x-www-form-urlencoded";
            request.Headers.Add("Origin", "http://irm.cninfo.com.cn");
            request.UserAgent =
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36";
            request.Referer = "http://irm.cninfo.com.cn/ircs/interaction/allQuestionsForSzse.do";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";

            stringBuilder.Append($"condition.dateFrom={startTime}" +
                                 $"&condition.dateTo={endTime}" +
                                 $"&condition.stockcode=" +
                                 $"&condition.keyWord=" +
                                 $"&condition.status=" +
                                 $"&condition.searchType=code" +
                                 $"&condition.questionCla=" +
                                 $"&condition.questionAtr=" +
                                 $"&condition.marketType=Z" +
                                 $"&condition.searchRange=" +
                                 $"&condition.questioner=" +
                                 $"&condition.questionerType=" +
                                 $"&condition.loginId=" +
                                 $"&condition.provinceCode=" +
                                 $"&condition.plate=" +
                                 $"&pageNo={pageNo}" +
                                 $"&categoryId=" +
                                 $"&code=" +
                                 $"&pageSize=10" +
                                 $"&source=2" +
//                                 $"&requestUri=/ircs/interaction/allQuestionsForSzse.do" +
                                 $"&requestMethod=POST");

            var formData = stringBuilder.ToString();
            Stream stream = request.GetRequestStream();
            Encoding encoding = Encoding.UTF8;
            byte[] data = encoding.GetBytes(formData);

            stream.Write(data, 0, data.Length);
            stream.Close();

            HttpWebResponse response = (HttpWebResponse) request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            return retString;
        }

        private static string GetAnswerHtml(String startTime, String endTime, string pageNo)
        {
            var stringBuilder = new StringBuilder();
            var url = "http://irm.cninfo.com.cn/ircs/interaction/lastRepliesForSzse.do";

            HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);

            request.Method = WebRequestMethods.Http.Post;

            request.ContentType = "application/x-www-form-urlencoded";
            request.UserAgent =
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
            request.Referer = "http://irm.cninfo.com.cn/ircs/interaction/lastRepliesForSzse.do";
            request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
            stringBuilder.Append($"condition.dateFrom={startTime}" +
                                 $"&condition.dateTo={endTime}" +
                                 $"&condition.stockcode=" +
                                 $"&condition.keyWord=" +
                                 $"&condition.status=" +
                                 $"&condition.searchType=code" +
                                 $"&condition.questionCla=" +
                                 $"&condition.questionAtr=" +
                                 $"&condition.marketType=Z" +
                                 $"&condition.searchRange=" +
                                 $"&condition.questioner=" +
                                 $"&condition.questionerType=" +
                                 $"&condition.loginId=" +
                                 $"&condition.provinceCode=" +
                                 $"&condition.plate=" +
                                 $"&pageNo={pageNo}" +
                                 $"&categoryId=" +
                                 $"&code=" +
                                 $"&pageSize=10" +
                                 $"&source=2" +
//                                 $"&requestUri=%2Fircs%2Finteraction%2FlastRepliesForSzse.do" +
                                 $"&requestMethod=GET");

            var formData = stringBuilder.ToString();
            Stream stream = request.GetRequestStream();
            Encoding encoding = Encoding.UTF8;
            byte[] data = encoding.GetBytes(formData);

            stream.Write(data, 0, data.Length);
            stream.Close();

            HttpWebResponse response = (HttpWebResponse) request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            return retString;
        }

        public static List<QAnswer> GetQuestion(DateTime startTime, DateTime endTime)
        {
            return GetQAnswers(startTime, endTime, true);
        }

        private static List<QAnswer> GetQAnswers(DateTime startTime, DateTime endTime, bool onlyQuestion)
        {
            int pageNo = 1;
            var qAnswers = new List<QAnswer>();
            var startTimeStr = startTime.ToString("u").Substring(0, 10);
            var endTimeStr = endTime.ToString("u").Substring(0, 10);
            var htmlParser = new HtmlParser();

            while (true)
            {
                var html = onlyQuestion
                    ? GetQuestionHtml(startTimeStr, endTimeStr, pageNo + "")
                    : GetAnswerHtml(startTimeStr, endTimeStr, pageNo + "");

                var htmlDocument = htmlParser.Parse(html);

                var questionSelectors = htmlDocument.QuerySelectorAll("div.msgBox").ToList();
                var answerSelectors = htmlDocument.QuerySelectorAll("div.answerBox").ToList();

                var i = 0;
                var crawlingQuestion = questionSelectors.Select(m =>
                {
                    var nameCodeHtml = m.QuerySelector("a.blue2").InnerHtml;
                    var nameCodeMatch = Regex.Match(nameCodeHtml, "(.*?)\\((.*?)\\)");
                    var name = nameCodeMatch.Groups[1].Value.Trim();
                    var code = nameCodeMatch.Groups[2].Value.Trim();

                    var questionSelector = m.QuerySelector("a.cntcolor");
                    var question = questionSelector.InnerHtml.Trim();
                    var questionIdMatch = Regex.Match(questionSelector.GetAttribute("href"),
                        ".*?questionId=([0-9]*?)&.*?");
                    var questionId = questionIdMatch.Groups[1].Value;
                    var questionTime = m.QuerySelector("a.date").InnerHtml;
                    var dateTime = DateTime.ParseExact(questionTime, "yyyy年MM月dd日 HH:mm",
                        System.Globalization.CultureInfo.CurrentCulture);
                    String answer = null;
                    DateTime answerTime = DateTime.MinValue;

                    if (!onlyQuestion)
                    {
                        answer = answerSelectors[i].QuerySelector("a.cntcolor").InnerHtml.Trim();
                        var answerTimeHtml = answerSelectors[i].QuerySelector("a.date").InnerHtml.Trim();
                        answerTime = DateTime.ParseExact(answerTimeHtml, "yyyy年MM月dd日 HH:mm",
                            System.Globalization.CultureInfo.CurrentCulture);
                    }

                    i++;
                    return new QAnswer
                    {
                        Question = question,
                        Pid = "SZ."+questionId,
                        Code = code,
                        QuestionTime = dateTime,
                        Answer = answer,
                        AnswerTime = answerTime,
                        From = "SZ"
                    };
                }).ToList();

                if (onlyQuestion && crawlingQuestion.Any(m => m.QuestionTime <= startTime))
                {
                    var answers = crawlingQuestion.Where(m => m.QuestionTime >= startTime).ToList();
                    qAnswers.AddRange(answers);
                    break;
                }

                if (!onlyQuestion && crawlingQuestion.Any(m => m.AnswerTime <= startTime))
                {
                    var answers = crawlingQuestion.Where(m => m.AnswerTime >= startTime).ToList();
                    qAnswers.AddRange(answers);
                    break;
                }

                if (crawlingQuestion.Count == 0)
                {
                    break;
                }

                if (qAnswers.Any() && qAnswers.Any(m => m.Pid.Equals(crawlingQuestion[0].Pid)))
                {
                    break;
                }

                qAnswers.AddRange(crawlingQuestion);
                pageNo++;
            }
            return qAnswers;
        }

        public static List<QAnswer> GetAnswers(DateTime startTime, DateTime endTime)
        {
            return GetQAnswers(startTime, endTime, false);
        }
    }
}